package display

import "code.google.com/p/go8/chip8"

type ScreenPainter struct {
	painter          Painter
	bgColor, fgColor Color
}

func NewScreenPainter(p Painter) *ScreenPainter {
	return &ScreenPainter{painter: p}
}

func (p *ScreenPainter) SetBackgroundColor(c Color) {
	p.bgColor = c
}

func (p *ScreenPainter) SetForegroundColor(c Color) {
	p.fgColor = c
}

func (p *ScreenPainter) Paint(screen chip8.Screen) {
	p.painter.ClearScreen(Color{0, 0, 0})
	w, h := screen.Size()
	pixelSize := p.calculatePixelSize(w, h)
	offsetX, offsetY := p.calculateScreenOffsets(pixelSize, w, h)

	fgRects := make([]Rect, 0, w*h)
	bgRects := make([]Rect, 0, w*h)
	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			rect := Rect{
				offsetX + x*pixelSize,
				offsetY + y*pixelSize,
				pixelSize,
				pixelSize,
			}
			if screen.IsSet(x, y) {
				fgRects = append(fgRects, rect)
			} else {
				bgRects = append(bgRects, rect)
			}
		}
	}

	p.drawScreen(bgRects, fgRects)
	p.painter.Show()
}

func (p *ScreenPainter) calculatePixelSize(screenW, screenH int) int {
	canvasW, canvasH := p.painter.CanvasSize()
	w, h := canvasW/screenW, canvasH/screenH
	return min(w, h)
}

func min(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func (p *ScreenPainter) calculateScreenOffsets(pixelSize, screenW, screenH int) (xOffset, yOffset int) {
	canvasW, canvasH := p.painter.CanvasSize()
	xOffset = (canvasW - pixelSize*screenW) / 2
	yOffset = (canvasH - pixelSize*screenH) / 2
	return
}

func (p *ScreenPainter) drawScreen(bgRects, fgRects []Rect) {
	if len(bgRects) > 0 {
		p.painter.FillRects(bgRects, p.bgColor)
	}
	if len(fgRects) > 0 {
		p.painter.FillRects(fgRects, p.fgColor)
	}
}
